import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.net.URL;
import com.jme.bounding.BoundingBox;
import com.jme.math.FastMath;
import com.jme.math.Quaternion;
import com.jme.math.Vector3f;
import com.jme.scene.Node;
import com.jme.scene.Spatial;
import com.jme.util.export.binary.BinaryImporter;
import com.jmex.model.converters.FormatConverter;
import com.jmex.model.converters.ObjToJme;
import com.jmex.physics.DynamicPhysicsNode;
import com.jmex.physics.PhysicsSpace;
import com.jmex.physics.material.Material;


public class Car extends Node {
    private static final long serialVersionUID = 1L;
    // Машины аралыг дүрслэх зангилаа
    private DynamicPhysicsNode chassisNode;
    // урд хойд хоёр дугуйнуудыг тогтоон барих үүрэгтэй
    private Suspension rearSuspension, frontSuspension;

    public Car( final PhysicsSpace pSpace ) {
        super("car");
        createChassi(pSpace);
        createSuspension(pSpace);   
    }
    public void setPosition( float x, float y, float z ) {
        chassisNode.clearDynamics();
        chassisNode.getLocalTranslation().set( x, y, z );
        chassisNode.getLocalRotation().loadIdentity();
        frontSuspension.resetPosition();
        rearSuspension.resetPosition();
    }
    public void setRotation( float x, float y, float z, float w ) {
        chassisNode.clearDynamics();
        chassisNode.getLocalRotation().set( x, y, z, w );
        frontSuspension.resetPosition();
        rearSuspension.resetPosition();
    }

    /**
     * x утга нь аралын төвөөс x тэнхлэгийн дагуух зай
     * y утга нь suspension-ий байрлах өндөр
     * z аралын төвөөс хоёр талын тэнхлэгийн дагуух шилжлэгийн утга
     *
     * @param pSpace physics space
     */
    private void createSuspension( final PhysicsSpace pSpace ) {
        frontSuspension = new Suspension( pSpace, chassisNode, CarData.FRONT_SUSPENSION_OFFSET, true );
        this.attachChild( frontSuspension );
        rearSuspension = new Suspension( pSpace, chassisNode, CarData.REAR_SUSPENSION_OFFSET, false );
        this.attachChild( rearSuspension );
    }


    private void createChassi( final PhysicsSpace pSpace ) {
        chassisNode = pSpace.createDynamicNode();
        chassisNode.setName("chassiPhysicsNode");
        Node chassisModel = new Node();      
        
    	Spatial spatial;
    	URL folder= Car.class.getClassLoader().getResource("data/hummer_jeep/");	
		URL model = Car.class.getClassLoader().getResource("data/hummer_jeep/hummer_jeep.obj");
        FormatConverter converter=new ObjToJme();
        converter.setProperty("mtllib", folder);
        converter.setProperty("texdir", folder);
        ByteArrayOutputStream BO=new ByteArrayOutputStream();
        try {
            converter.convert(model.openStream(), BO);
            spatial=(Spatial) BinaryImporter.getInstance().load(new ByteArrayInputStream(BO.toByteArray()));
            spatial.setLocalScale(4f); 
            chassisModel.attachChild(spatial);
            chassisModel.setModelBound(new BoundingBox());
            chassisModel.updateModelBound();          
        } catch (Exception e) {
        	System.err.println("Уучлаарай жийпний модел ачаалах хэсэгт алдаа гарлаа");            
        }       
        chassisNode.setLocalRotation(new Quaternion().fromAngleAxis(FastMath.PI, new Vector3f(0,1,0)));
        chassisModel.setLocalScale(0.8f);
        chassisNode.attachChild(chassisModel);

        // олон машин хэрэглэх гэж байгаа бол false болгох хэрэгтэй
        chassisNode.generatePhysicsGeometry(false);
        chassisNode.setMaterial(Material.IRON);
        chassisNode.setMass(CarData.CHASSIS_MASS);
        this.attachChild(chassisNode);
    }

    /**
	 * Машиныг хурдасгах
     * @param 1 утга бол урагшаа маажина -1 бол хойшоогоо маажина
     */
    public void accelerate( final int direction ) {
        rearSuspension.accelerate( direction );
        frontSuspension.accelerate( direction );
    }

    /**
     * Хурдасгалыг зогсоох
     */
    public void releaseAccel() {
        rearSuspension.releaseAccel();
        frontSuspension.releaseAccel();
    }

    /**
     * Урд хоёр дугуйг мужийлгах
     *
     * @param 1 утга баруун -1 бол зүүн зүгрүү мужийна
     */
    public void steer( final float direction ) {
        frontSuspension.steer( direction );
    }

    /**
     * Мужийлгалтыг эгцлэх
     */
    public void unsteer() {
        frontSuspension.unsteer();
    }

    private final Vector3f tmpVelocity = new Vector3f();
    
    /**
     * HUD-ийг хэрэглэж машины хурдны утгыг авах
     *
     * @return Машины хурд
     */
    public float getLinearSpeed() {
        return chassisNode.getLinearVelocity( tmpVelocity ).length();
    }

    /**
     * ChaseCamera буюу машиныг дагах камерт хэрэг болно
     *
     * @return Машины арлыг дүрслэх node-ийг буцаана
     */
	public DynamicPhysicsNode getChassis() {
		return chassisNode;
	}

}
